package net.apps123.fragment;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;

import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.Toast;

import net.apps123.commonaclasses.MyBaseClass;
import net.apps123.mqtt.MQClient;
import net.apps123.soundmeter.FuPinResultActivity;
import net.apps123.soundmeter.HunXiangDetailActivity;
import net.apps123.soundmeter.KuoShengMainActivity;
import net.apps123.soundmeter.MyClassKuoSheng;
import net.apps123.soundmeter.R;
import net.apps123.soundmeter.RemoteActivity;
import net.apps123.utils.IpUtils;
import net.apps123.view.SplAdapter;
import net.apps123.view.SplDataBean;
import net.apps123.view.SplView;

import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;

import java.io.IOException;
import java.net.InetAddress;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Set;

import pub.devrel.easypermissions.AfterPermissionGranted;
import pub.devrel.easypermissions.AppSettingsDialog;
import pub.devrel.easypermissions.EasyPermissions;


/**
 * A simple {@link Fragment} subclass.
 * Use the {@link FuPinFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class FuPinFragment extends Fragment  implements EasyPermissions.PermissionCallbacks,
        EasyPermissions.RationaleCallbacks{
    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

    public static HashMap<String, short[]> deviceList = new HashMap<>();

    static private MyClassKuoSheng myClass = null;
    private static final int PERMISSION_CAMERA = 1000; //权限的请求码唯一即可
    String[] perms = {Manifest.permission.RECORD_AUDIO, Manifest.permission.INTERNET,
            Manifest.permission.ACCESS_NETWORK_STATE, Manifest.permission.ACCESS_WIFI_STATE}; //一些权限用逗号隔

    private Button startBtn;
    private Context mContext;
    private SplView splView;
    private ListView remoteSplList;
    private List<SplDataBean> splList = new ArrayList<>();
    private SplAdapter splAdapter;

    private View mainView ;

    public FuPinFragment() {
        // Required empty public constructor
    }

    /**
     * 构造函数
     */
    public static FuPinFragment newInstance() {
        return new FuPinFragment();
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment FuPinFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static FuPinFragment newInstance(String param1, String param2) {
        FuPinFragment fragment = new FuPinFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        mainView = inflater.inflate(R.layout.fragment_fu_pin, container, false);
        mainView.findViewById(R.id.genBtn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                playWav(v);
            }
        });
        mContext = getActivity();
        mainView.findViewById(R.id.ResultBtn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {



                startActivity(new Intent(getActivity(), FuPinResultActivity.class));
                if (mediaPlayer != null) {
                    mediaPlayer.stop();
                }
                startBtn.performClick();
            }
        });

        //
        initRemoteDevice(mainView);

        startBtn = mainView.findViewById(R.id.startBtn);
        startBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String cmdStr = "";
                if (startBtn.getText().equals("开始")){
                    cmdStr = "start1";
                }else {
                    cmdStr = "stop1";
                }
                String finalCmdStr = cmdStr;
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            KuoShengMainActivity.getMqttClient().publish("setApp", finalCmdStr.getBytes(), 1, false);
//                            playWav( v);
                        } catch (MqttException e) {
                            e.printStackTrace();
                        }
                    }
                }).start();
            }
        });
        mainView.findViewById(R.id.remoteBtn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(getActivity(), RemoteActivity.class));
            }
        });

        if (myClass != null)
            myClass.InitViews( mainView);

        myClass = MyClassKuoSheng.Instance( mainView);
        myClass.fs = myClass.onFastSlow(MyBaseClass.FastSlow.Slow);
//        myClass.onOn_Off(MyBaseClass.On_Off.Off);
//		findViewById(R.id.textView21).performClick();
        doSomethingWithCamera();



        String[] starArray = {"控制端", "被控制端"};
        ArrayAdapter<String> starAdapter = new ArrayAdapter<String>(getActivity(), R.layout.item_select, starArray);
//        starAdapter.setDropDownViewResource(R.layout.item_dropdown);
        Spinner sp = mainView.findViewById(R.id.controlSpinner);
        sp.setPrompt("请选择");
        sp.setAdapter(starAdapter);
        sp.setSelection(0);
        sp.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                if (position == 0) {
                    startBtn.setVisibility(View.VISIBLE);
                } else {
                    startBtn.setVisibility(View.GONE);
                }
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });

        return mainView;
    }


    //重置数据
    public void onReset(View view) {
        myClass.onReset();
    }

    //暂停
    public void onPC(View view) {
        myClass.onPause();
    }

    //fft 倍频程切换
    public void onSwap(View view) {
        myClass.selection = myClass.onSwap(myClass.selection);
    }

    //开始继续
    public void onOn_Off(View view) {
        if (EasyPermissions.hasPermissions(getActivity(), perms)) {
            //当前有权限时进行的操作
            if (myClass != null)
                myClass.InitViews(mainView);

            myClass = MyClassKuoSheng.Instance( mainView);
            myClass.fs = myClass.onFastSlow(MyBaseClass.FastSlow.Slow);
            myClass.on_off = myClass.onOn_Off(myClass.on_off);
        } else {
            //没有权限去申请权限
            EasyPermissions.requestPermissions(
                    this, "该权限仅是实现音频分析，请通过权限否则不能使用某些功能！", PERMISSION_CAMERA, perms);
        }

    }

    //快慢切换
    public void onFastSlow(View view) {
        myClass.fs = myClass.onFastSlow(myClass.fs);
    }

    //平均算法
    public void onMLN(View view) {
        myClass.mln = myClass.onMLN(myClass.mln);
    }

    @Override
    public void onPermissionsGranted(int i, @NonNull List<String> list) {
        Toast.makeText(getActivity(), "应用获得权限成功", Toast.LENGTH_LONG).show();
        String ipStr = IpUtils.getWifiIPAddress(getActivity());
        Log.d("====", "ipStr==" + ipStr);
    }

    @Override
    public void onPermissionsDenied(int i, @NonNull List<String> list) {
        if (EasyPermissions.somePermissionPermanentlyDenied(this, Arrays.asList(perms))) {
            //在权限弹窗中，用户勾选了'不在提示'且拒绝权限的情况触发
            new AppSettingsDialog.Builder(this).build().show(); //调用接口进入该应用的设置页面
        }

    }

    @Override
    public void onRationaleAccepted(int i) {

    }

    @Override
    public void onRationaleDenied(int i) {

    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        // 回调结果传递给EasyPermission
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);

    }

    /**
     * 权限请求方法可直接调用
     */
    @AfterPermissionGranted(PERMISSION_CAMERA)
    public void doSomethingWithCamera() {
        if (EasyPermissions.hasPermissions(getActivity(), perms)) {
            //当前有权限时进行的操作
            if (myClass != null)
                myClass.InitViews( mainView);

            myClass = MyClassKuoSheng.Instance(mainView);
            myClass.fs = myClass.onFastSlow(MyBaseClass.FastSlow.Slow);

            String ipStr = IpUtils.getWifiIPAddress(getActivity());
            Log.d("====", "ipStr==" + ipStr);

        } else {
            //没有权限去申请权限
            EasyPermissions.requestPermissions(
                    this, "该权限仅是实现音频分析，请通过权限否则不能使用某些功能！", PERMISSION_CAMERA, perms);
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == AppSettingsDialog.DEFAULT_SETTINGS_REQ_CODE) {
            Toast.makeText(getActivity(), "音频权限为" + EasyPermissions.hasPermissions(getActivity(),
                    perms), Toast.LENGTH_LONG).show();
        }
    }


    private MediaPlayer mediaPlayer;

    private void playWav(View view) {
        if (mediaPlayer != null && mediaPlayer.isPlaying()) {
            mediaPlayer.stop();
        }
        mediaPlayer = new MediaPlayer();
        mediaPlayer.reset();
        try {
            mediaPlayer.setDataSource(getActivity().getBaseContext(), Uri.parse("android.resource://"
                    + getActivity().getBaseContext().getPackageName() + "/" + R.raw.whie_noise_10s_48k));
            mediaPlayer.prepare();
            mediaPlayer.start();
            mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {

                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mediaPlayer != null) {
            mediaPlayer.stop();
            mediaPlayer.release();
        }


    }

    @Override
    public void onStart() {
        super.onStart();
        if (KuoShengMainActivity.getMqttClient() != null) {
            KuoShengMainActivity.getMqttClient().setCallback(new MqttCallback() {
                @Override
                public void connectionLost(Throwable throwable) {
                    Log.d("=====", "====connectionLost");
                    Toast.makeText(mContext, "===connectionLost==", Toast.LENGTH_SHORT).show();
                }

                @Override
                public void messageArrived(String s, MqttMessage mqttMessage) throws Exception {
                    Log.d("=====", "====messageArrived");
                    String mqttContent = new String(mqttMessage.getPayload());
//                    Log.d("====", mqttContent.length() + "====" + mqttContent);

//                    Log.d("==cmdStr==" + s, "====" + mqttContent);

                    if (!s.equals("setApp")) {
                        return;
                    }
                    String cmdStr = mqttContent.substring(0, 4);



                    getActivity().runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                if (cmdStr.contains("star")) {
//									startBtn.performClick();
                                    myClass.on_off = myClass.onOn_Off(myClass.on_off);
                                    startBtn.setText("结束");
                                } else if (cmdStr.contains("stop")) {
//									startBtn.performClick();
                                    startBtn.setText("开始");
                                    myClass.on_off = myClass.onOn_Off(myClass.on_off);
                                } else {
                                    Log.d("==data==", "数据来了");
                                    Intent intent = new Intent("com.gasFragment");
                                    byte[] revData = new byte[mqttMessage.getPayload().length - 4];
                                    System.arraycopy(mqttMessage.getPayload(), 4, revData, 0, mqttMessage.getPayload().length - 4);
                                    intent.putExtra("data", revData);

                                    byte[] ipByte = new byte[4];
                                    System.arraycopy(mqttMessage.getPayload(), 0, ipByte, 0, 4);
                                    InetAddress inetAddress = InetAddress.getByAddress(ipByte);
                                    String ipStr = inetAddress.getHostAddress();

                                    intent.putExtra("ipStr", ipStr);
                                    mContext.sendBroadcast(intent);
                                    updateRemoteDevice( intent);
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    });
                }

                @Override
                public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
                    Log.d("=====", "=====deliveryComplete");
                }
            });
        }
    }

    private void initRemoteDevice(View mainView) {
        splView = mainView.findViewById(R.id.splView);
        remoteSplList = mainView.findViewById(R.id.remoteSplList);
        splList = new ArrayList<>();
        splAdapter = new SplAdapter(getActivity(), splList);
        remoteSplList.setAdapter(splAdapter);
    }

    private void updateRemoteDevice(Intent intent) {
        byte[] dataArr = intent.getExtras().getByteArray("data");
        Log.d("=======", "ReceiveBroadCast==" + dataArr.length);
        String ipStr = intent.getStringExtra("ipStr");
        if (dataArr == null || dataArr.length < 1278) {
            return;
        }
        short[] buffer = new short[dataArr.length / 2];
        ByteBuffer.wrap(dataArr).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(buffer);

        deviceList.put(ipStr, buffer);
        if (splView != null) {
            splView.updateView(buffer, "");
        }

        splList.clear();

        Set<String> keySet = deviceList.keySet();
        for (String key : keySet) {
            System.out.println("key:" + key + " , value:");
            SplDataBean splDataBean = new SplDataBean(key, deviceList.get(key));
            splList.add(splDataBean);
        }
        splAdapter.notifyDataSetChanged();

    }




}
